package org.jradweb.core.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jradweb.core.utils.StringUtils;
import org.jradweb.core.web.JFlashScope;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import org.springframework.web.servlet.view.RedirectView;

/**
 * Super Class of Controller
 * 
 * Created On 2008-3-12
 * 
 * @author <a href="mailto:wagzhi@gmail.com">Paul Wang</a>
 * @version $Id: JMultiActionController.java 98 2008-04-11 09:44:25Z wagzhi $
 */
public abstract class JMultiActionController extends MultiActionController {
	public static final String FLASH_SCOPE="session_flash_scope";
	
	
	private String name;
	//protected List<String> flash=new ArrayList<String>();
	
	
	 
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String methodName=this.getMethodNameResolver().getHandlerMethodName(request);
		Map<String,Object> modelMap=new HashMap<String,Object>();
		modelMap.put("controllers", this.getControllers(request).values());
		modelMap.put("flash",this.getFlash(request));
		
		ModelAndView mv= super.handleRequestInternal(request, response);
		
		
		if(mv.getView()!=null&&RedirectView.class.isInstance(mv.getView())){
			return mv;
		}
		else{
			 if(!mv.hasView()){				 
				 String viewName=this.getControllerName() + "/" + methodName;
				 mv.setViewName(viewName);
			 }
			
			mv.getModel().putAll(modelMap);
			getFlash(request).next();		
			return mv;
		}
		
		
	}
	public JFlashScope getFlash(HttpServletRequest request){
		JFlashScope flash= (JFlashScope)request.getSession(true).getAttribute(FLASH_SCOPE);
		if(flash==null){
			flash=new JFlashScope();
			request.getSession().setAttribute(FLASH_SCOPE, flash);
		}
		return flash;
	}

	public JMultiActionController() {
		super();
	}

	

	public ModelAndView render(String view, Map<String, Object> params) {
		return new ModelAndView(this.getControllerName() + "/" + view, params);
	}
	
	
	public ModelAndView render(HttpServletRequest request, String view,
			Map<String, Object> params) {
		params.put("controllers", this.getControllers(request).values());
		return new ModelAndView(this.getControllerName() + "/" + view, params);
	}

	public String getControllerName() {
		String name = this.getClass().getName();
		name = name.substring(name.lastIndexOf('.') + 1);
		name = name.substring(0, name.lastIndexOf("Controller"));
		return StringUtils.lowerCaseFirst(name);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Map<String, JMultiActionController> getControllers(
			HttpServletRequest request) {
		WebApplicationContext ctx = this.getApplicationContext(request);
		return ctx.getBeansOfType(JMultiActionController.class);
	}
	
	public ModelAndView redirect(String controller,String action,Map params){
		return new ModelAndView(new RedirectView("/"+controller+"/"+action+".html",true),params);	
	}
	public ModelAndView redirect(String action,Map params){
		return new ModelAndView(new RedirectView("/"+this.getName().toLowerCase()+"/"+action+".html",true),params);	
	}

	/**
	 * get spring application context
	 * 
	 * @param pageContext
	 * @return
	 */
	public WebApplicationContext getApplicationContext(
			HttpServletRequest request) {

		return (WebApplicationContext) request
				.getSession()
				.getServletContext()
				.getAttribute(
						WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
	}

}
